#include "Thread.h"

#include <iostream>
#include <stdexcept>

using std::cerr;
using std::endl;


/*
 * General thread entry point for a subclass of Thread.
 */
int threadMain(void * data)
{
	if(data == NULL) // couldn't use dynamic_cast, so we can only check for NULL, not type...
	{
		throw std::logic_error("Trying to start a thread with threadMain from Thread.cpp without Thread object pointer as data.");
	}

	Thread *t = static_cast<Thread*>(data);

	t->init();
	while(!t->isQuitting())
	{
		t->run();
	}
	t->shutDown();
	return 0;
}


Thread::Thread(const std::string & threadName):
	thread(NULL),
	quit(false),
	name(threadName)
{
}


Thread::~Thread()
{
	if(!isRunning())
	{
		cerr << "Thread subclass object " << getName() << " is destructed before it was stopped!" << endl;
	}
}


void Thread::start()
{
	if(isRunning())
	{
		throw std::logic_error(std::string("Trying to start a thread that's already running! Threadname: ") + getName());
	}
	thread = SDL_CreateThread(threadMain, static_cast<void*>(this));
}


void Thread::stop()
{
	if(!isRunning())
	{
		throw std::logic_error(std::string("Trying to stop a thread that's not running! Threadname: ") + getName());
	}
	quit = true;
	SDL_WaitThread(thread, NULL);
	thread = NULL;
}


bool Thread::isRunning() const
{
	return (thread != NULL);
}


bool Thread::isQuitting() const
{
	return quit;
}


const std::string & Thread::getName() const
{
	return name;
}


//void Thread::kill()
//{
//	cerr << "TRYING TO KILL A THREAD, THIS IS BAD PRACTICE!" << endl;
//	if(!isRunning())
//	{
//		throw std::logic_error("Trying to kill a thread that's not running!");
//	}
//	SDL_KillThread(thread, NULL);
//	thread = NULL;
//}


